package com.codemonkey.lq.extend.excelverification.impl;

import java.util.ArrayList;
import java.util.List;

import com.codemonkey.lq.common.util.StringHelper;
import com.codemonkey.lq.extend.excelverification.AbstractVerifier;
import com.codemonkey.lq.extend.excelverification.CellContext;
import com.codemonkey.lq.extend.excelverification.spi.Continuable;

/**
 * 主要借鉴自Mybatis中的MixedSqlNode,所有Verifier实例的最终形态就是它; 必须全部通过
 * 
 * 类似的还有RoutingStatementHandler
 * 
 * MixVerifier  mixVerifier = new MixVerifier(Lists.newArrayList(){{
 * 		add(new IntergeVerifier());
 * 		add(new DoubleVerifier());
 * 		add(new FloatVerifier());
 * }});
 * 
 * --------------------------- 支持多类型验证, 例如针对number类型, 内部分别调度给IntegerVerifier,DoubleVerifier,FloatVerifier等. 自身只负责调度转发.
 * 
 * 借鉴自Mybatis中的MixedSqlNode,RoutingStatementHandler
 * 
 */
public class MixVerifier extends AbstractVerifier {
	private final List<AbstractVerifier> verifiers = new ArrayList<AbstractVerifier>();

	public MixVerifier() {
		super();
	}

	public void addVerifier(AbstractVerifier verifier) {
		verifiers.add(verifier);
	}

	public void addVerifiers(List<AbstractVerifier> otherVerifier) {
		verifiers.addAll(otherVerifier);
	}

	public int getInnerVerifierCount() {
		return verifiers.size();
	}

	/* 循环所有的校验,顺序执行
	 * @see com.codemonkey.lq.extend.excelverification.AbstractVerifier#doVerify(com.codemonkey.lq.extend.excelverification.CellContext)
	 */
	@Override
	protected boolean doVerify(CellContext cellContext) {
		for (AbstractVerifier verifier : verifiers) {

			if (verifier.verify(cellContext)) {
				// 经过上一个Verifier处理之后, 传递给接下来的Verifier继续处理	
				// NO OP ; 自定义校验时; 用户自己抉择
			} else {
				// 验证失败

			}

			// 是否继续接下来的Verifier
			if (verifier instanceof Continuable) {
				Continuable continuableVerifier = (Continuable) verifier;
				if (!continuableVerifier.isContinue(cellContext)) {
					break;
				}
			}
		}

		if (cellContext.getFailMsg().length() == 0) {
			return true;
		}

		return false;
	}

	@Override
	public String getReadableFailMsg(CellContext cellContext) {
		StringBuilder sBuilder = new StringBuilder();
		for (AbstractVerifier verifier : verifiers) {
			final String readableFailMsg = verifier.getReadableFailMsg(cellContext);
			if (StringHelper.isEmpty(readableFailMsg)) {
				continue;
			}
			sBuilder.append(readableFailMsg);
			sBuilder.append(System.lineSeparator());
		}

		return sBuilder.toString();
	}

}
